<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
    //     //箭头函数的写法

    //     //传统函数
    //     function fn () {}   //函数声明式
    //     var fn = function () {} //函数表达式

    //    //箭头函数
    //     var fn = () => {}    //基本箭头函数 

    //    //正常函数有返回值
    //    function fn () {
    //         return v + 1
    // } 
    //     //箭头函数中有返回值
    //    var fn = v => v + 1

    //    //正常函数返回值是对象
    //    function fn () {
    //        return {obj: v}
    //    }    

    //    //箭头函数返回值是对象
    //    var fn = v => ({obj: v})

    //箭头函数this案例
    // var fn = function () {
    //     return () => {console.log(this.name)}
    // }
    // var obj1 = {
    //     name: '张三'
    // }
    // var obj2 = {
    //     name: '李四'
    // }
    // //全局变量
    // var name = '王五'
    // obj1.fn = fn
    // obj2.fn = fn
    // /* 第一次调用触发return中的箭头函数，此时箭头函数指向上一层（fn）函数的作用域,
    //     因为obj1是调用者，所以此时的this指向的是obj1。输出结果为张三
    // */
    // obj1.fn()()
    // obj2.fn()()

    // /* 直接调用fn,触发箭头函数，箭头函数同样指向fn的作用域，此时无调用者，因此箭头函数
    //     指向全局作用域。输出为王五    
    // */
    // fn()()

    //箭头函数不受call的影响
    // var user = {
    //     name: '张三',
    //     fn:function () {
    //         var obj = {
    //             name: '李四'
    //         }
    //         var f = () => this.name
    //         // 箭头函数只受定义位置的影响
    //         return f.call(obj)
    //     }
    // }

    // console.log(user.fn())

    // 箭头函数中需要通过Rest方法获取参数
    // var foo = (...arguments) => {
    //     console.log(arguments)
    // }
    // foo(1, 2, 3)

    //Generator函数,箭头函数不可使用yield会语法报错
    // function *fn() {
    //     yield 1;
    //     yield 2;
    //     yield 3;

    // }
    // var f = fn()
    // console.log(f)
    // console.log(f.next())
    // console.log(f.next())
    // console.log(f.next())


    //箭头函数实际应用

//     export default {
//         name:'App',
//         data(){
//             return{
//                 message:'这是一个定义内容'
//             }
//         },
//     methods: {
//       open() {
//         this.$alert('这是一段内容', '标题名称', {
//           confirmButtonText: '确定',
//           callback: action => {
//             this.$message({
//               type: 'info',
//               message: `action: ${ action }`
//             });
//           }
//         });
//       }
//     }
//   }

  //正常函数写法
//   export default {
//         name:'App',
//         data(){
//             return{
//                 message:'这是一个定义内容'
//             }
//         },
//     methods: {
//       open() {
//         var self = this
//         this.$alert('这是一段内容', '标题名称', {
//           confirmButtonText: '确定',
//           //报错原因：callback是在alert组件内部调用
//           callback: function () {
//               console.log(this, 'this')
//             this.$message({
//               type: 'info',
//               message: `action: ${ action }`
//             });
//           }
//         });
//       }
//     }
//   }

// //  箭头函数在setTimeout中，
// foo() {
//     //箭头函数指向foo
//     setTimeout(() => {
//         console.log('arge:', arguments);
//     },0)
// }

//面试案例
var name = 'window'
var obj = {
    name:'obj',
    methods: () => {
        //外层无其他函数，this指向全局
        console.log(this.name)  //obj.methods(),obj.fn两个的指向
    }, 
    fn: function (cb) {
        cb()
    }
}
obj.fn1 = function() {
    obj.fn(() => {console.log(this.name)})
}
//fn1
var fn1 = obj.fn1
//输出结果是window
obj.methods()    
//() => {console.log(this.name)此段为箭头函数定义的位置
obj.fn(() => {console.log(this.name)})
//前面无指定调用者fn1指向全局
fn1()
//此时是obj在调用fn1，所以this指向的是obj，箭头函数是指向上一级作用域所以输出为obj    
obj.fn1()
</script>
</body>
</html>